package reflect;

import classroom1.five.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:周次煜
 * Date: 2024-04-28
 * Time：16:20
 */
public class ReflectTest {


    public static void main3(String[] args)  {


      try {
          Class<Reflect> c=(Class<Reflect>)Class.forName("reflect.Reflect");


            System.out.println("============ 获得该类中与参数类型匹配的公有的构造方法 ====== ");

          /**
           * 用 getDeclaredConstructor 得到某个指定参数类型的构造器
           * 并 用 setAccessible 来打开这个构造器权限
           * 最后 用 newInstance 来实例化该类 的对象
           *
           */




          // 得到 private 修饰的构造器
            Constructor<Reflect> con=(Constructor<Reflect>)c.getDeclaredConstructor(String.class,int.class);

            // 打开该构造器的入口
            con.setAccessible(true);


          // 用 构造器 实例化一个对象
          Reflect reflect= con.newInstance("zcy",20);
          System.out.println(reflect);


          System.out.println("====== 获得该类某个公有方法 =======");
          Constructor<Reflect> con1=c.getConstructor();

          // 公有的构造器是不需要 授权的
//          con1.setAccessible(true);

          // 实例化一个
          Reflect reflect1=con1.newInstance();

          System.out.println(reflect1);


          /**
           * 获得 成员方法
           * 第一步： 利用 getDeclaredMethod 来得到我们的成员方法
           * 注意有参数十，要 + 参数类型.class
           * 若要修改参数类型就就可以将
           */

          // 所有的是可以调用公共的，但需要打开修改的入口
          Method method= c.getDeclaredMethod("function", String.class);

          // 修改的入口
          method.setAccessible(true);

        Reflect reflect2=c.newInstance();

        // invoke 授权含义
        method.invoke(reflect,"我尝试修改下成员方法！");

        // 公共的不可以调用私用的
        Method method1=c.getMethod("sleep");
        method1.setAccessible(true);
          System.out.println(method1.toString());
          method1.invoke(reflect2);

      } catch (ClassNotFoundException e) {
          throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
          throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
          throw new RuntimeException(e);
      } catch (InstantiationException e) {
          throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
          throw new RuntimeException(e);
      }


    }

    public static void main(String[] args) {
        try {
           Class<?> c= Class.forName("reflect.Reflect");
           Reflect reflect=(Reflect) c.newInstance();
            System.out.println("======获得类的完整路径名字=======");
            String s= c.getName();
            System.out.println(s);


            /**
             *  通过 getDeclaredField 来 获取某个类中的字段 包括 private 修饰的
             *  通过 setAccessible 来打开修改的权限
             *
             *  并且还可以在指定的类型下进行 成员方法的修改
             *
             */

            System.out.println("=============获得所有或某个公有的属性对象=======");
            Field[] fields=  c.getFields();
            System.out.println(Arrays.toString(fields));
            Field f= c.getDeclaredField("name");


           // 打开修改权限
            f.setAccessible(true);

            // 进行修改
            f.set(reflect,"zhoubaibai");
            System.out.println(reflect);

//            Declared 修饰的就是所有的属性
            System.out.println("==========获得所有属性对象=========");
            Field[] f1= c.getDeclaredFields();
            System.out.println(Arrays.toString(f1));

        }  catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main1(String[] args)  {

    Class<?> a=null;


        /**
         *   首先用 Class.forname 创建 类对象
         *   用 newInstance 来创建实例化对象
         *
         */


    try {
        a= Class.forName("reflect.Reflect");
       Reflect s =(Reflect) a.newInstance();
        System.out.println(s);
     } catch (ClassNotFoundException e) {
         throw new RuntimeException(e);
     } catch (InstantiationException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }


    }
}
